package com.mazaiting.gateway.security;

import com.mazaiting.gateway.domain.SecureIgnoreBean;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 弃用, 使用 payload 向下游传递数据
 * TOKEN 数据转换过滤器
 * 1. GET 和 DELETE 请求将登录 ID 存储到请求头中
 * 2. POST 和 PUT 请求将登录 ID 存储到body 中
 */
@Deprecated
@Slf4j
//@Component
@RequiredArgsConstructor
public class TokenTransformFilter implements GlobalFilter, Ordered {

    private final SecureIgnoreBean secureIgnoreBean;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        ServerHttpRequest request = exchange.getRequest();
//        String path = request.getPath().toString();
//        log.info("进入了 TOKEN 数据转换过滤器, path:[{}]", path);
//        // 请求内容类型
//        MediaType contentType = request.getHeaders().getContentType();
//        // 请求方法
//        HttpMethod method = request.getMethod();
//        // 判断是否在忽略 token 的列表中
//        boolean ignoreMatch = secureIgnoreBean.getUrls().stream().anyMatch(s -> PathPatternParser.defaultInstance.parse(s).matches(PathContainer.parsePath(path)));
////        if (ignoreMatch || Objects.isNull(contentType) || Objects.isNull(method)
////        if (ignoreMatch || Objects.isNull(method) || HttpMethod.GET == method) {
//        if (ignoreMatch) {
//            return chain.filter(exchange);
//        } else {
//            return ReactiveSecurityContextHolder.getContext()
//                    .map(SecurityContext::getAuthentication)
//                    .cast(JwtAuthenticationToken.class)
//                    .flatMap(authentication -> {
//                        Jwt jwt = authentication.getToken();
//                        if (Objects.isNull(jwt)) {
//                            return WebFluxUtil.writeErrorInfo(exchange.getResponse(), ResultCode.ACCESS_UNAUTHORIZED);
//                        }
//                        // 此处 instant 与 date 差 8 个小时, 但由于只比较是否过期, 所以不需要转换为 date
//                        Instant expiresAt = jwt.getExpiresAt();
//                        if (Objects.isNull(expiresAt) || expiresAt.isBefore(Instant.now())) {
//                            return WebFluxUtil.writeErrorInfo(exchange.getResponse(), ResultCode.TOKEN_INVALID_OR_EXPIRED);
//                        }
//                        // 获取数据
//                        Map<String, Object> claims = ((Jwt) authentication.getPrincipal()).getClaims();
//
//                        if (HttpMethod.POST == method || HttpMethod.PUT == method) {
//
//                            ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
//                            // 修改请求体
//                            Mono<String> bodyMono = serverRequest.bodyToMono(String.class).flatMap(oldBody -> {
//                                // 新的请求体
//                                String newBody = oldBody;
//                                // 目前只处理 json 和 multipart 表单两种请求类型
//                                if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
//                                } else if (MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
//                                    newBody = modifyBodyByJson(oldBody, claims);
//                                }
//                                return Mono.just(newBody);
//                            });
//                            BodyInserter<Mono<String>, ReactiveHttpOutputMessage> bodyInserter = BodyInserters.fromPublisher(bodyMono, String.class);
//                            HttpHeaders headers = new HttpHeaders();
//                            headers.putAll(exchange.getRequest().getHeaders());
//                            headers.remove(HttpHeaders.CONTENT_LENGTH);
//                            CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
//                            // 修改头
//                            return bodyInserter.insert(outputMessage, new BodyInserterContext())
//                                    .then(Mono.defer(() -> {
//                                        ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
//
//                                            @NonNull
//                                            @Override
//                                            public HttpHeaders getHeaders() {
//                                                long contentLength = headers.getContentLength();
//                                                HttpHeaders httpHeaders = new HttpHeaders();
//                                                httpHeaders.putAll(super.getHeaders());
//                                                if (contentLength > 0) {
//                                                    httpHeaders.setContentLength(contentLength);
//                                                } else {
//                                                    httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
//                                                }
//                                                return httpHeaders;
//                                            }
//
//                                            @NonNull
//                                            @Override
//                                            public Flux<DataBuffer> getBody() {
//                                                return outputMessage.getBody();
//                                            }
//                                        };
//                                        return chain.filter(exchange.mutate().request(decorator).build());
//                                    }));
//
//                        } else if (HttpMethod.DELETE == method || HttpMethod.GET == method) {
//                            // 将登录 ID 放在请求头中
//                            ServerHttpRequest newRequest = exchange.getRequest()
//                                    .mutate()
//                                    .header(AuthConstant.AUTH_LOGIN_ID, String.valueOf(claims.get(AuthConstant.AUTH_LOGIN_ID)))
//                                    .build();
//                            return chain.filter(exchange.mutate().request(newRequest).build());
//                        } else {
//                            return chain.filter(exchange);
//                        }
//                    });
//        }
        return chain.filter(exchange);
    }

//    /**
//     * 内容类型为空 json, 修改请求体, 添加用户信息
//     *
//     * @param oldBody 原始请求体
//     * @param claims  jwt 内容
//     * @return 新请求体
//     */
//    private String modifyBodyByJson(String oldBody, Map<String, Object> claims) {
//        JSONObject jsonObject = JSON.parseObject(oldBody);
//        jsonObject.put(AuthConstant.AUTH_LOGIN_ID, claims.get(AuthConstant.AUTH_LOGIN_ID));
//        return jsonObject.toJSONString();
//    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }
}